﻿<!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
-->

<UserControl x:Class="Microsoft.Windows.Controls.Samples.SeriesZoomSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:datavis="clr-namespace:Microsoft.Windows.Controls.DataVisualization;assembly=Microsoft.Windows.Controls.DataVisualization"             
    xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization">

    <UserControl.Resources>
        <ControlTemplate TargetType="charting:Chart" x:Key="ZoomChartTemplate">
            <Border 
                Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Padding="5">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <datavis:Title
                        Content="{TemplateBinding Title}"
                        Style="{TemplateBinding TitleStyle}"/>

                    <Grid Grid.Row="1">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>

                        <datavis:Legend
                            x:Name="Legend"
                            Title="{TemplateBinding LegendTitle}"
                            Style="{TemplateBinding LegendStyle}"
                            Grid.Column="1"/>

                        <ScrollViewer 
                            x:Name="ScrollArea" BorderThickness="0" 
                            HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden">
                            <Grid x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}" Margin="0,10,0,20" >
                                <Grid x:Name="PlotArea" Style="{TemplateBinding PlotAreaStyle}">
                                    <Grid x:Name="GridLinesContainer" />
                                    <Grid x:Name="SeriesContainer" />
                                </Grid>
                            </Grid>
                        </ScrollViewer>
                    </Grid>
                </Grid>
            </Border>
        </ControlTemplate>

    </UserControl.Resources>

    <StackPanel Background="White">

        <ContentControl Content="Zooming a Series" Style="{StaticResource Header}"/>

        <charting:Chart HorizontalAlignment="Left" Width="450" Height="320" Template="{StaticResource ZoomChartTemplate}" x:Name="ZoomChart" Title="Zoomable">
            <charting:LineSeries
                Title="Widget Popularity"
                ItemsSource="{StaticResource WidgetPopularity}"
                IndependentValueBinding="{Binding Date}"
                DependentValueBinding="{Binding Percent}" />
            <charting:LineSeries
                Title="Gizmo Popularity"
                ItemsSource="{StaticResource GizmoPopularity}"
                IndependentValueBinding="{Binding Date}"
                DependentValueBinding="{Binding Percent}" />
        </charting:Chart>

        <StackPanel Margin="5,10,0,0" Orientation="Horizontal" >
            <TextBlock Text="Zoom:" />
            <Slider Margin="5,0,0,0" Width="250" Minimum="0" Maximum="500" ValueChanged="ZoomChanged" />
        </StackPanel>


        <src:SourceViewer xmlns:src="clr-namespace:Microsoft.Windows.Controls.Samples;assembly=Microsoft.Windows.Controls.Samples.Common" xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <src:SourceFile Path="SeriesZoomSample.xaml">
    <src:SourceFile.Source>
      <sys:String>&lt;!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
--&gt;

&lt;UserControl x:Class="Microsoft.Windows.Controls.Samples.SeriesZoomSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:datavis="clr-namespace:Microsoft.Windows.Controls.DataVisualization;assembly=Microsoft.Windows.Controls.DataVisualization"             
    xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"&gt;

    &lt;UserControl.Resources&gt;
        &lt;ControlTemplate TargetType="charting:Chart" x:Key="ZoomChartTemplate"&gt;
            &lt;Border 
                Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Padding="5"&gt;
                &lt;Grid&gt;
                    &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition Height="Auto"/&gt;
                        &lt;RowDefinition Height="*"/&gt;
                    &lt;/Grid.RowDefinitions&gt;

                    &lt;datavis:Title
                        Content="{TemplateBinding Title}"
                        Style="{TemplateBinding TitleStyle}"/&gt;

                    &lt;Grid Grid.Row="1"&gt;
                        &lt;Grid.ColumnDefinitions&gt;
                            &lt;ColumnDefinition Width="*"/&gt;
                            &lt;ColumnDefinition Width="Auto"/&gt;
                        &lt;/Grid.ColumnDefinitions&gt;

                        &lt;datavis:Legend
                            x:Name="Legend"
                            Title="{TemplateBinding LegendTitle}"
                            Style="{TemplateBinding LegendStyle}"
                            Grid.Column="1"/&gt;

                        &lt;ScrollViewer 
                            x:Name="ScrollArea" BorderThickness="0" 
                            HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden"&gt;
                            &lt;Grid x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}" Margin="0,10,0,20" &gt;
                                &lt;Grid x:Name="PlotArea" Style="{TemplateBinding PlotAreaStyle}"&gt;
                                    &lt;Grid x:Name="GridLinesContainer" /&gt;
                                    &lt;Grid x:Name="SeriesContainer" /&gt;
                                &lt;/Grid&gt;
                            &lt;/Grid&gt;
                        &lt;/ScrollViewer&gt;
                    &lt;/Grid&gt;
                &lt;/Grid&gt;
            &lt;/Border&gt;
        &lt;/ControlTemplate&gt;

    &lt;/UserControl.Resources&gt;

    &lt;StackPanel Background="White"&gt;

        &lt;ContentControl Content="Zooming a Series" Style="{StaticResource Header}"/&gt;

        &lt;charting:Chart HorizontalAlignment="Left" Width="450" Height="320" Template="{StaticResource ZoomChartTemplate}" x:Name="ZoomChart" Title="Zoomable"&gt;
            &lt;charting:LineSeries
                Title="Widget Popularity"
                ItemsSource="{StaticResource WidgetPopularity}"
                IndependentValueBinding="{Binding Date}"
                DependentValueBinding="{Binding Percent}" /&gt;
            &lt;charting:LineSeries
                Title="Gizmo Popularity"
                ItemsSource="{StaticResource GizmoPopularity}"
                IndependentValueBinding="{Binding Date}"
                DependentValueBinding="{Binding Percent}" /&gt;
        &lt;/charting:Chart&gt;

        &lt;StackPanel Margin="5,10,0,0" Orientation="Horizontal" &gt;
            &lt;TextBlock Text="Zoom:" /&gt;
            &lt;Slider Margin="5,0,0,0" Width="250" Minimum="0" Maximum="500" ValueChanged="ZoomChanged" /&gt;
        &lt;/StackPanel&gt;



    &lt;/StackPanel&gt;
&lt;/UserControl&gt;
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SeriesZoomSample.xaml.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Linq;
using System.Diagnostics;
using System.Windows.Media;
using System.ComponentModel;

namespace Microsoft.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// Charting sample that demonstrates zooming.
    /// &lt;/summary&gt;
    [Sample("Zoom", DifficultyLevel.Scenario)]
    [Category("DataVisualization")]
    public partial class SeriesZoomSample : UserControl
    {
        /// &lt;summary&gt;
        /// Caching of the ChartArea template part.
        /// &lt;/summary&gt;
        private Panel chartArea;

        /// &lt;summary&gt;
        /// Gets the ChartArea.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;TemplatePart ChartArea&lt;/returns&gt;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by ZoomChanged.")]
        private Panel ChartArea
        {
            get
            {
                if (chartArea == null)
                {
                    chartArea = GetLogicalChildrenBreadthFirst(ZoomChart).Where(element =&gt; element.Name.Equals("ChartArea")).FirstOrDefault() as Panel;
                }

                return chartArea;
            }
        }

        /// &lt;summary&gt;
        /// Caching of the ScrollArea template part.
        /// &lt;/summary&gt;
        private ScrollViewer scrollArea;

        /// &lt;summary&gt;
        /// Gets the ScrollArea.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;TemplatePart ScrollArea&lt;/returns&gt;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by an event handler in XAML.")]
        private ScrollViewer ScrollArea
        {
            get
            {
                if (scrollArea == null)
                {
                    scrollArea = GetLogicalChildrenBreadthFirst(ZoomChart).Where(element =&gt; element.Name.Equals("ScrollArea")).FirstOrDefault() as ScrollViewer;
                }
                return scrollArea;
            }
        } 

        /// &lt;summary&gt;
        /// Initializes a new instance of the ZoomIntoChartSample class.
        /// &lt;/summary&gt;
        public SeriesZoomSample()
        {
            InitializeComponent();

            this.Loaded += ZoomIntoChartSample_Loaded;
        }

        /// &lt;summary&gt;
        /// Force an update of the chart.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The ZoomIntoChartSample instance.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        private void ZoomIntoChartSample_Loaded(object sender, RoutedEventArgs e)
        {
            // force synchronous layout pass
            ZoomChart.UpdateLayout();

            // and force initial zoom 
            UpdateChart(0);
        }
        
        /// &lt;summary&gt;
        /// Handles the changing of the zoomlevel.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The zoom slider.&lt;/param&gt;
        /// &lt;param name="e"&gt;Event arguments.&lt;/param&gt;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by an event handler in XAML.")]
        private void ZoomChanged(object sender, RoutedPropertyChangedEventArgs&lt;double&gt; e)
        {
            Debug.Assert(ChartArea != null &amp;&amp; ScrollArea != null, "Zoom should not be called before layout has occurred");

            double zoom = e.NewValue;

            UpdateChart(zoom);
        }

        /// &lt;summary&gt;
        /// Updates the chart to zoom with the correct zoom factor.
        /// &lt;/summary&gt;
        /// &lt;param name="zoom"&gt;The percentage of zoom we wish to apply.&lt;/param&gt;
        private void UpdateChart(double zoom)
        {
            ChartArea.Width = ScrollArea.ViewportWidth + (ScrollArea.ViewportWidth * zoom / 100.0);
        }

        /// &lt;summary&gt;
        /// Helper function that returns a list of the visual children.
        /// &lt;/summary&gt;
        /// &lt;param name="parent"&gt;Element whose visual children will be returned.&lt;/param&gt;
        /// &lt;returns&gt;A collection of visualchildren.&lt;/returns&gt;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by ChartArea and ScrollArea.")]
        private IEnumerable&lt;FrameworkElement&gt; GetLogicalChildrenBreadthFirst(FrameworkElement parent)
        {
            Debug.Assert(parent != null, "The parent cannot be null.");

            Queue&lt;FrameworkElement&gt; queue =
                new Queue&lt;FrameworkElement&gt;(GetVisualChildren(parent).OfType&lt;FrameworkElement&gt;());

            while (queue.Count &gt; 0)
            {
                FrameworkElement element = queue.Dequeue();
                yield return element;

                foreach (FrameworkElement visualChild in GetVisualChildren(element).OfType&lt;FrameworkElement&gt;())
                {
                    queue.Enqueue(visualChild);
                }
            }
        }

        /// &lt;summary&gt;
        /// Helper function that returns the direct visual children of an element.
        /// &lt;/summary&gt;
        /// &lt;param name="parent"&gt;The element whose visual children will be returned.&lt;/param&gt;
        /// &lt;returns&gt;A collection of visualchildren.&lt;/returns&gt;
        private IEnumerable&lt;DependencyObject&gt; GetVisualChildren(DependencyObject parent)
        {
            Debug.Assert(parent != null, "The parent cannot be null.");

            int childCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int counter = 0; counter &lt; childCount; counter++)
            {
                yield return VisualTreeHelper.GetChild(parent, counter);
            }
        }
    }
}</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
</src:SourceViewer>



    </StackPanel>
</UserControl>
